/*
 * Copyright (C) 2011 Dirk Weißenborn, dirk.weissenborn@gmail.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.weissenborn.colabtex.client;

import java.util.HashMap;
import java.util.Map;

import com.google.gwt.event.shared.EventBus;
import com.google.gwt.place.shared.PlaceController;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.weissenborn.colabtex.client.events.UserUpdatedEvent;
import com.weissenborn.colabtex.client.service.EtherpadService;
import com.weissenborn.colabtex.client.service.EtherpadServiceAsync;
import com.weissenborn.colabtex.client.view.DashboardView;
import com.weissenborn.colabtex.client.view.GroupCreationView;
import com.weissenborn.colabtex.client.view.GroupListView;
import com.weissenborn.colabtex.client.view.GroupManagerView;
import com.weissenborn.colabtex.client.view.HeaderView;
import com.weissenborn.colabtex.client.view.LoginView;
import com.weissenborn.colabtex.client.view.MainView;
import com.weissenborn.colabtex.client.view.TexView;


/**
 * A factory for managing client objects throughout the session
 */
public interface ClientFactory {
	
	/**
	 * Gets the event bus.
	 *
	 * @return the event bus
	 */
	public EventBus getEventBus();
	
	/**
	 * Gets the place controller.
	 *
	 * @return the place controller
	 */
	public PlaceController getPlaceController();
	
	/**
	 * Adds the handlers.
	 */
	public void addHandlers();
	
	/**
	 * Gets the group list view.
	 *
	 * @return the group list view
	 */
	public GroupListView getGroupListView();	
	
	/**
	 * Gets the login view.
	 *
	 * @return the login view
	 */
	public LoginView getLoginView();
	
	/**
	 * Sets the session id.
	 *
	 * @param sessionID the new session id
	 */
	public void setSessionID(String sessionID);
	
	/**
	 * Gets the session id.
	 *
	 * @return the session id
	 */
	public String getSessionID();
	
	/**
	 * Sets the user.
	 *
	 * @param id the new user
	 */
	public void setUser(String id);
	
	/**
	 * Gets the user.
	 *
	 * @return the user
	 */
	public User getUser();
	
	/**
	 * Checks if is logged in.
	 *
	 * @return true, if is logged in
	 */
	public boolean isLoggedIn();
	
	/**
	 * Sets the logged in.
	 *
	 * @param loggedIn sets user to be logged in or not logged in
	 */
	public void setLoggedIn(boolean loggedIn);
	
	/**
	 * Gets the dashboard view.
	 *
	 * @return the dashboard view
	 */
	public DashboardView getDashboardView();
	
	/**
	 * Gets the header view.
	 *
	 * @return the header view
	 */
	public HeaderView getHeaderView();
	
	/**
	 * Gets the main view.
	 *
	 * @return the main view
	 */
	public MainView getMainView();
	
	/**
	 * Gets the group creation view.
	 *
	 * @return the group creation view
	 */
	public GroupCreationView getGroupCreationView();
	
	/**
	 * Gets the group manager view.
	 *
	 * @return the group manager view
	 */
	public GroupManagerView getGroupManagerView();
	
	/**
	 * Gets the tex view.
	 *
	 * @return the tex view
	 */
	public TexView getTexView();
	
	/**
	 * The Class User that contains all information about the user logged in in a session.
	 */
	public class User {
		
		/** The id. */
		String id;
		
		/** The permissions. */
		Map<String, String> permissions;
		
		/** The event bus. */
		EventBus eventBus;
		
		/**
		 * Instantiates a new user.
		 *
		 * @param bus the bus
		 */
		public User(EventBus bus) {
			permissions = new HashMap<String, String>();
			eventBus = bus;
		}
		
		/**
		 * Gets the id.
		 *
		 * @return the id
		 */
		public String getId() {
			return id;
		}
		
		/**
		 * Sets the id.
		 *
		 * @param id the new id
		 */
		public void setId(String id) {
			this.id = id;
		}
		
		/**
		 * Gets the access permissions for groups
		 *
		 * @return the permissions
		 */
		public Map<String, String> getPermissions() {	
			if(permissions == null)
				permissions = new HashMap<String, String>();
			return permissions;
		}
		
		/**
		 * Adds an access permission for specified group.
		 *
		 * @param groupName the group name
		 * @param role the role
		 */
		public void addPermission(String groupName, String role) {
			permissions.put(groupName, role);
		}
		
		/**
		 * Sets the permissions from the database
		 */
		public void setPermissions() {
			EtherpadServiceAsync service = EtherpadService.Util.getInstance();
			AsyncCallback<Map<String,String>> callback = new AsyncCallback<Map<String,String>>() {
				public void onSuccess(Map<String, String> result) {
					permissions=result;
					eventBus.fireEvent(new UserUpdatedEvent());	
				}
				
				public void onFailure(Throwable caught) {
					Window.alert("No connection to server");
					permissions = new HashMap<String, String>();
					eventBus.fireEvent(new UserUpdatedEvent());	
				}
			};
			
			service.listGroups(id, callback);
		}
		
	}
}
